/**
 * List.java
 * Autores: Jennifer Valdez 10189
 *          Gustavo Sánchez 10313
 *          Sergio Molina   10256
 * Fecha de entrega: 21 de noviembre de 2011
 * Descripcion: Es la clase que define las funciones, posee
 *          parametros, nombre y cuerpo que son las partes de la funcion
 *          Le da el formato de una función para luego poder evaluarla.
 * 
 */

import java.util.HashMap;

public class Funcion {
    //atributos
    private String name;            //Nombre de la funcion
    private String[] keys;          //Nombre de los parametros ingresados
    private HashMap parametros;     //Hashmap con los valores de los parametros
    private List expresion;         //Lista utilizada para evaluar el resultado
    private String[] body;          //Cuerpo de la funcion
    private String[] bodyTemp;      //Funcion temporal en la cual se sustituiran los caracteres de los parametros por los valores ingresados
    
    /**
     * Constructor de la clase Funcion, crea un nuevo hashmap para parametros
     * iguala name a la primera casilla de declaracion, copia los parametros a
     * keys y el cuerpo a body
     * @param declaracion Es la declaracion de la funcion en formato nombre(parametros)
     * @param cuerpo Es el cuerpo de la funcion, lo que realizara al ser llamada
     */
    public Funcion(String[] declaracion, String[] cuerpo){
        name = declaracion[0];
        parametros = new HashMap();
        keys = new String[declaracion.length-3];
        //Guarda los parametros en keys y en el hashmap parametros
        for (int i = 2; i<declaracion.length-1; i++){
            parametros.put(declaracion[i], null);
            keys[i-2] = declaracion[i];
        }
        body=cuerpo;    
    }
    
    /**
     * Verifica que los parametros esten bien ingresados, luego en bodyTemp
     * sustituye los caracteres de parametros por los valores ingresados por el
     * usuario y por ultimo crea un nuevo objeto lista con bodytemp como expresion
     * y llama a evualuar, lo que devuelve es el resultado de evaluar.
     * @param paramactuales Es un vector que tiene los valores actuales de los parametros
     * @param func Hashmap de las funciones declaradas hasta el momentos
     * @return El resultado de la operacion
     */
    public String llamarFuncion(String[] paramactuales, HashMap func){
        //Verifica sintaxis
        if(keys.length==paramactuales.length){
            //Se cloba body en bodyTemp
            bodyTemp = body.clone();
            //Se le asignan los nuevos valores de los parametros en el hashmap
            //parametros
            for(int i=0; i< keys.length;i++){
                   parametros.remove(keys[i]);
                   parametros.put(keys[i], paramactuales[i]);
            }
            //Se sustituyen la letras de parametros por los valores actuales de estos
            for(int i=0;i<bodyTemp.length;i++){
                if(parametros.containsKey(bodyTemp[i])){
                    bodyTemp[i]= (String)parametros.get(bodyTemp[i]);
                }
            }
            //Se crea una nueva lista utilizando bodyTemp como expresion
            expresion = new List(bodyTemp, func);
            return expresion.evaluar();
        }
        else
            return " ";
    }
    
    /**
     * Devuelve el nombre de la funcion
     * @return El nombre en String de la funcion
     */
    public String getName(){
        return name;
    }
    
    /**
     * Devuelve cuantos parametros tiene esta funcion
     * @return Devuelve el int con el numero de parametros de la funcion
     */
    public int getKeysLength(){
        return keys.length;
    }
    
}
